“In the past, the initial setup of all the necessary development tools was a tedious job. First, you had to find the right download link for the .phar along with the corresponding signature in the correct version. Then you would download the data. Once the .phar file was successfully tested, it was still marked as executable. The process had to be repeated for every tool needed – that’s a lot of work.
Luckily, we now have an alternative called PHIVE (PHAR Installation and Verification Environment). The tool developed by Arne Blankerts and Sebastian Heuer takes a lot of work off the hands of the developer. Using PHIVE, different PHAR archives can be defined as dependencies, much like in Composer. This information is available in phive.xml.
Application and installation
A simple phive install starts the process of downloading the tools defined in phive.xml. Subsequently, the hashes (SHA1, SHA256 or SHA512) of the respective archives are verified in the same way as their OpenPGP/GnuPG signature. To avoid repeated download of the respective archives, the archives are stored by default in the home directory of the user in ~/.phive.
To integrate PHIVE into an existing project, PHIVE should first be installed on the systems you are using. How this works exactly is described in Listing 1.
wget -O phive.phar https://phar.io/releases/phive.phar wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc gpg --keyserver pool.sks-keyservers.net --recv-keys 0x9D8A98B29B2D5D79 gpg --verify phive.phar.asc phive.phar chmod +x phive.phar sudo mv phive.phar /usr/local/bin/phive
The subsequent installation of php-cs-fixer for example is really quite simple by using phive install php-cs-fixer. In this example, php-cs-fixer is set as an alias and points to the GitHub repository FriendsOfPHP/PHP-CS-Fixer. Alternative installation options are shown in Listing 2.
phive install psh phive install shopwareLabs/sw-cli-tools phive install https://phar.phpunit.de/phpunit-4.8.6.phar
PHIVE creates a phive.xml file (see Listing 3) if it does not already exist. The defined dependencies are set in this file, much like in composer.json.
<?xml version="1.0" encoding="UTF-8"?> <phive xmlns="https://phar.io/phive"> <phar name="php-cs-fixer" version="^2.12.2" installed="2.12.2" location="./tools/php-cs-fixer" /> <phar name="shopwarelabs/psh" version="^1.2.0" installed="1.2.0" location="psh" /> <phar name="phpstan" version="^0.10.1" installed="0.10.1" location="./tools/phpstan" /> <phar name="shopwarelabs/sw-cli-tools" version="^0.0.1" installed="0.0.1" location="./tools/sw" /> </phive>
By default, the archives are located in the document root in the Tools directory. If you prefer to have a copy instead of a symbolic link, just add —copy to the command. If you prefer to have the archives in another directory or in the document root instead, you can change this using the —target parameter.
No more steps are required to integrate PHIVE into a project. To make the switch from composer dev-requirements as easy as possible, you can use phive composer to search composer.json for known aliases and then install them in a selection dialog.
You can update the PHAR archives used by running a simple phive update. PHIVE itself can be updated to the most current level using phive selfupdate.
Installing your own PHAR archives
To install your own PHAR archives using PHIVE, you have a number of options available: based on GitHub releases (phive install username/project), registered as an alias on phar.io (phive install alias) or an explicit URL (phive install https://server/file-1.0.0.phar).
Now using our PSH tool, we’ll take a closer look at how it all works via GitHub releases.
The following prerequisites must be met: we need to have a GPG key for the project, in addition the public key on the SKS key servers must be known and an already generated PHAR file must be available.
We go to the console and enter the following command: gpg -u [email protected] –detach-sign –output psh.phar.asc psh.phar. By doing so, we sign the psh.phar file and obtain a psh.phar.asc signature file. These two files will now be added as an attachment at https://github.com/shopwareLabs/psh/releases to the corresponding version.
That would be it! Now you can install the archive via phive install shopwareLabs/psh. Since we have created an alias for psh [3], a simple phive install psh is also possible. If you want to register an alias, you just need to create a pull request on phar-io/phar.io.
OpenPGP/GnuPG
GnuPG is the standard for signing archives and is also used to sign git commits and git tags. It is important that you use a cryptographically secure tool to verify the integrity of files/archives and the authenticity of the provided signature. OpenPGP offers the ideal conditions for this.
For the verification process to work properly (for example, gpg -verify …), the public part of the private key used for signing must be known on the system that performs the verification. Therefore, the public key must be imported through its ID. Once the public key is on the so-called keyring, signatures associated with that key can be verified.
As things stand today, as long as the private key is stored securely and confidentially, it is virtually impossible for anyone other than the owner of the private key to create a signature. If a potential attacker takes another private key to sign the compromised archive, the validation will fail. This process involves the key ID and fingerprints, which cannot be falsified.
Of course, the PHAR archive and the associated signature can be falsified, but the attacker would not match the official signing key, which will make the verification fail. PHIVE provides a warning when a signature key has changed and actively prompts the user to verify and, if necessary, confirm that this change is correct.
This leaves one issue pending: theoretically, a falsified key could be used for the first installation of a PHAR archive and PHIVE would not notice because there are currently no possibilities to detect that. In a future version, registered aliases for PHIVE will also be able also store your public key data [4].
Therefore, the only solution at the moment is to manually check the respective fingerprint. For example, the PHIVE website lists the fingerprint used in the footer of the website.
OpenSSL
While OpenSSL signatures can be used to verify that a specified file has not been changed after signing, they do not provide any additional identity information. Since this would make the signatory undetectable, any person could sign a compromised archive using OpenSSL. So unfortunately, there is no easy way to recognize the difference between that and an official unchanged archive.
OpenSSL signatures, as they are implemented in ext-phar, have no option to protect the signatory. To make this work, we need a CA setup with certificates and not just private and public keys. But in terms of the effort involved, this is a completely different league when compared to creating your own OpenPGP key for each project.
Conclusion
With PHIVE, Arne Blankerts and Sebastian Heuer have scored really big by creating a solution that can finally manage .phar files easily and reliably. Updating these files and storing the versions used has never been easier. In addition, this concept saves a lot of space in the respective repository. Thanks to the use of OpenPGP/GnuPG, the entire process is protected by current cryptographic standards. We are now using PHIVE on a trial basis in a new software project and so far, our experiences have been consistently positive. Little by little, we are converting our existing projects to PHIVE. If you are not using PHIVE yet, the time to start is now.
Links & literature
[1] Wikipedia, „Dependency Hell“: https://en.wikipedia.org/wiki/Dependency_hell
[2] GitHub, “Add infection to PHIVE (PHAR Installation and Verification Environment)”: https://github.com/infection/infection/issues/134
[3] GitHub, “adding psh and sw-cli-tools to repositories.xml”: https://github.com/phar-io/phar.io/commit/d88298103c9fe7a99fdc00d930f505c83b67ada0
[4] GitHub, “Add support for trusted keys in repositories.xml”: https://github.com/phar-io/phive/issues/158
Material from phar.io was used to create the article